//创建用户相关的小仓库
import { defineStore } from 'pinia';
//引入接口
import { reqLogin, reqLogout, reqUserInfo } from '@/api/user';
//引入数据类型
import type { UserState } from './types/type';
import type { loginFormData, loginResponseData, userInfoReponseData } from "@/api/user/type";
//引入常量路由
import { constantRoute, asnycRoute, anyRoute } from '@/router/routers';
//引入操作本地存储的工具方法
import { SET_TOKEN, GET_TOKEN, REMOVE_TOKEN } from '@/utils/token';
//@ts-expect-error
import cloneDeep from 'lodash/cloneDeep';
import router from '@/router';

// 用于过滤当前用户需要展示的异步路由
function filterAsyncRoute(asyncRoute: any, routes: any) {
    return asyncRoute.filter((item: any) => {
        if (routes.includes(item.name)) {
            if (item.children && item.children.length > 0) {
                item.children = filterAsyncRoute(item.children, routes)
            }
            return true
        }
    })
}
// 深克隆
function deepClone(obj: any): any {
    if (obj === null || typeof obj !== 'object') {
        return obj; // 基本数据类型或 null
    }

    const clone: any = Array.isArray(obj) ? [] as unknown as any : Object.assign({}, obj);

    for (const key in obj) {
        if (obj.hasOwnProperty(key)) {
            clone[key] = deepClone((obj as { [key: string]: any })[key]);
        }
    }

    return clone;
}
//创建用户小仓库
let useUserStore = defineStore('User', {
    //小仓库存储数据的地方
    state: (): UserState => {
        return {
            token: GET_TOKEN(),//用户的唯一标识
            menuRoutes: constantRoute,//仓库存储生成菜单需要数组(路由)
            username: '',
            avatar: '',
            buttons: []
        }
    },
    //异步/逻辑的地方
    actions: {
        //用户登录的方法
        async userLogin(data: loginFormData) {
            //登录请求
            let result: loginResponseData = await reqLogin(data);
            //登录成功：成功200->token
            //登录失败：失败201->登录失败错误信息
            if (result.code == 200) {
                //pinia仓库存储一下token
                //由于pinia|vuex存储数据其实利用js对象
                this.token = (result.data as string);
                //本地存储持久化存储一份
                SET_TOKEN((result.data as string))
                //能保证当前async函数返回一个成功的promise
                return 'ok'
            } else {
                return Promise.reject(new Error(result.data));
            }
        },
        //获取用户信息方法
        async userInfo() {

            let result: userInfoReponseData = await reqUserInfo();
            if (result.code == 200) {
                this.username = result.data.name;
                this.avatar = result.data.avatar;
                this.buttons = result.data.buttons;
                //计算当前用户需要展示的异步路由
            
                const userAsyncRoute = filterAsyncRoute(
                    deepClone(asnycRoute),
                    result.data.routes,
                )
                console.log(userAsyncRoute);
                
                //菜单需要的数据整理完毕
                this.menuRoutes=[...constantRoute,...userAsyncRoute,...anyRoute];
                // 追加注册路由
                [...userAsyncRoute,anyRoute].forEach((route:any)=>{
                    router.addRoute(route)
                })
                console.log(router.getRoutes());
                
                return 'ok';
            } else {
                // 获取用户信息失败
                return Promise.reject(new Error(result.message))
            }

        },
        // 退出登录
        async userlogout() {
            //目前没有mock接口：退出登录接口（通知服务器本地用户唯一标识失效）
            let result: any = await reqLogout();
            if (result.code == 200) {
                //目前没有mock接口，退出登录接口（通知服务器本地用户唯一标识失效）
                this.token = '';
                this.username = '';
                this.avatar = '';
                REMOVE_TOKEN();
                return 'ok';
            } else {
                return Promise.reject(new Error(result.message));
            }
        }
    },
    //计算属性
    getters: {

    }
})
//对外暴露获取小仓库的方法
export default useUserStore;